package com.ujson.chat.common.codec;

import com.ujson.base.common.exception.GlobalException;
import com.ujson.chat.common.proto.MessageProto;
import com.ujson.chat.common.utils.Constants;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 自定义Proto解码器
 */
public class ProtoDecoder extends ByteToMessageDecoder {
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        byteBuf.markReaderIndex();

        // 读取数据的长度不够head-length长度, 返回等下次读取
        if (byteBuf.readableBytes() < 4) {
            return ;
        }

        int length = byteBuf.readInt();
        // head-length长度为0，认为非法数据
        if (length <= 0) {
            throw new GlobalException("illegal data.");
        }

        // 数据不够等一等
        if (length > byteBuf.readableBytes()) {
            byteBuf.resetReaderIndex();
            return ;
        }
        int magic = byteBuf.readShort();
        if (magic != Constants.MAGIC) {
            throw new GlobalException("");
        }
        int version = byteBuf.readInt();
        byte[] bytes = null;
        if (byteBuf.hasArray()) {
            // 堆缓冲
            bytes = byteBuf.slice().array();
        } else {
            // 直接缓冲区
            bytes = new byte[length];
            byteBuf.readBytes(bytes, 0, length);
        }
        MessageProto.Message message = MessageProto.Message.parseFrom(bytes);
        list.add(message);
    }
}
